package com.codebo.homiematchbackend.controller;

import com.alibaba.dashscope.app.Application;
import com.alibaba.dashscope.app.ApplicationParam;
import com.codebo.homiematchbackend.annotation.AuthCheck;
import com.codebo.homiematchbackend.config.AIConfig;
import com.codebo.homiematchbackend.constant.UserConstant;
import com.codebo.homiematchbackend.model.dto.AIChat.AIChatRequest;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


@Slf4j
@RestController
@RequestMapping(("/ai/chat"))
public class AIChatController
{
    @Resource
    private AIConfig aiConfig;

    private final ExecutorService io = Executors.newCachedThreadPool();
    private static final ObjectMapper MAPPER = new ObjectMapper();


    @AuthCheck(mustRole = UserConstant.DEFAULT_ROLE)
    @PostMapping(value = "/stream", produces = "text/event-stream")
    public SseEmitter streamChat(@RequestBody AIChatRequest aiChatRequest, HttpServletRequest httpServletRequest)
    {
        System.out.println("aiChatRequest = " + aiChatRequest);

        String API_KEY = aiConfig.getApiKey();
        String APP_ID = aiConfig.getApiId();
        SseEmitter emitter = new SseEmitter(300_000L); // 5分钟超时
        io.execute(() ->
        {
            try
            {
                ApplicationParam param = ApplicationParam.builder()
                        .apiKey(API_KEY)
                        .appId(APP_ID)
                        .messages(aiChatRequest.getMessages())
                        .incrementalOutput(true)   // 关键：增量
                        .build();

                Application application = new Application();
                application.streamCall(param)
                        .blockingForEach(chunk ->
                        {
                            String delta = chunk.getOutput().getText();
                            if (!Objects.equals(delta, ""))
                            {
                                String jsonStr = MAPPER.writeValueAsString(Map.of("data", delta));
                                emitter.send(SseEmitter.event()
                                        .name("delta")
                                        .data(jsonStr));
//                                emitter.send(SseEmitter.event().comment("flush"));
                                System.out.print(delta);
                            }

                        });
                emitter.send(SseEmitter.event().name("done").data(MAPPER.writeValueAsString(Map.of("data", "[DONE]"))));
                emitter.complete();
            } catch (Exception e)
            {
                log.error("stream error", e);
                try
                {
                    emitter.send(SseEmitter.event().name("error").data(MAPPER.writeValueAsString(Map.of("data", e.getMessage()))));
                } catch (IOException ignore)
                {
                }
                emitter.completeWithError(e);
            }
        });
        return emitter;
    }

}
